<template>
  <div id="app-container">
    <div id="app"></div>
    <div class="quake-info">
      <div><strong>Magnitude:</strong> <span id="mag"></span></div>
      <div><strong>Location:</strong> <span id="loc"></span></div>
      <div><strong>Date:</strong> <span id="date"></span></div>
    </div>
  </div>
</template>

<script>
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
dayjs.locale('zh-cn');

export default {
  data() {
    return {
      // 历史数据
      datasets: null,
      // map 地图对象实例
      map: null,
    };
  },
  mounted() {
    this._createBaseMap();

    window.dayjs = dayjs;
  },
  methods: {
    _createBaseMap() {
      mapboxgl.accessToken =
        'pk.eyJ1IjoiY2hhbnBmIiwiYSI6ImNsNG1qMDExejAwNDgzam8zcGtiMW5sNmwifQ.J4K5kbkjtcAABsmIW7Z0Tw';

      const map = new mapboxgl.Map({
        container: 'app',
        //自己绘制的样式地图令牌
        antialias: true, //抗锯齿
        style: 'mapbox://styles/mapbox/outdoors-v11',
        center: [-100.94121, 37.76132],
        zoom: 4,
      });

      this.map = map;
      window.map = map;

      const sevenDaysAgo = new Date(
        dayjs().subtract(7, 'day').$d
      ).toISOString();

      map.on('load', () => {
        map.addSource('earthquakes', {
          type: 'geojson',
          data: `https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&eventtype=earthquake&minmagnitude=1&starttime=${sevenDaysAgo}`,
          generateId: true, // 确保每个 features 都有一个唯一 id
        });

        map.addLayer({
          id: 'earthquakes-viz',
          type: 'circle',
          source: 'earthquakes',
          paint: {
            // circle-radius 的大小将由 feature-state 决定
            'circle-radius': [
              'case',
              // case 如果为 false，则默认 circle-radius 为 5
              // feature-state 后面的值为自行约定的命名
              // 在后面 setFeatureState 是指定该命名
              ['boolean', ['feature-state', 'isHover'], false],
              [
                'interpolate',
                ['linear'],
                ['get', 'mag'],
                1,
                8,
                1.5,
                10,
                2,
                12,
                2.5,
                14,
                3,
                16,
                3.5,
                18,
                4.5,
                20,
                6.5,
                22,
                8.5,
                24,
                10.5,
                26,
              ],
              5,
            ],
            'circle-stroke-color': '#000',
            'circle-stroke-width': 1,
            'circle-color': [
              'case',
              ['boolean', ['feature-state', 'isHover'], false],
              [
                'interpolate',
                ['linear'],
                ['get', 'mag'],
                1,
                '#fff7ec',
                1.5,
                '#fee8c8',
                2,
                '#fdd49e',
                2.5,
                '#fdbb84',
                3,
                '#fc8d59',
                3.5,
                '#ef6548',
                4.5,
                '#d7301f',
                6.5,
                '#b30000',
                8.5,
                '#7f0000',
                10.5,
                '#000',
              ],
              '#000',
            ],
          },
        });
      });

      let quakeID = 0;
      // 获取展示上的三个 dom
      const magDisplay = document.getElementById('mag');
      const locDisplay = document.getElementById('loc');
      const dateDisplay = document.getElementById('date');
      // 给指定 id 的 layer 绑定鼠标移动事件
      map.on('mousemove', 'earthquakes-viz', (event) => {
        // console.log('event :>> ', event);
        map.getCanvas().style.cursor = 'pointer';
        // 获取 properties 中的信息
        const quakeMagnitude = event.features[0].properties.mag; // 地震烈度
        const quakeLocation = event.features[0].properties.place; // 地震地址
        const quakeDate = new Date(event.features[0].properties.time); // 地震时间
        // 检测 features 是否存在，不存在则什么都不做
        if (event?.features?.length === 0) return;
        // 在左上角的展示框中显示相应的信息
        magDisplay.textContent = quakeMagnitude;
        locDisplay.textContent = quakeLocation;
        dateDisplay.textContent = quakeDate;
        console.log('event.features :>> ', event.features);
        // 判断 quakeID 是否存在，如果存在则调用 removeFeaturesState 将指定的 id 的 features 重置回默认状态
        if (quakeID) {
          map.removeFeatureState({
            source: 'earthquakes',
            id: quakeID,
          });
        }

        quakeID = event.features[0].id;

        /**
         * 给指定 id 的 features 设置 isHover 为 true
         * 这将触发 addLayer 时设置的 case 表达式为 true 的情况
         */
        map.setFeatureState(
          {
            source: 'earthquakes',
            id: quakeID,
          },
          {
            isHover: true,
          }
        );
      });
      // 给指定 id 的 layer 绑定mouseleave事件
      map.on('mouseleave', 'earthquakes-viz', () => {
        if (quakeID) {
          map.setFeatureState(
            {
              source: 'earthquakes',
              id: quakeID,
            },
            {
              isHover: false,
            }
          );
          quakeID = null;
          // 移除左上角展示的信息
          magDisplay.textContent = '';
          locDisplay.textContent = '';
          dateDisplay.textContent = '';
          // 重置鼠标样式
          map.getCanvas().style.cursor = '';
        }
      });
      // zoom变化时打印zoom值
      map.on('zoom', function (e) {
        console.log('zoom :>> ', e.target.getZoom());
      });
    },
  },
  beforeDestroy() {
    // this.map.removeLayer('custom-vector-tile-layer');
    this.map.remove();
    this.map = null;
  },
};
</script>

<style>
body {
  padding: 0;
  margin: 0;
  overflow: hidden;
}
#app {
  position: absolute;
  width: 100%;
  top: 0;
  bottom: 0;
}

/* 左上角设置的样式 */
.quake-info {
  position: absolute;
  font-family: sans-serif;
  margin-top: 5px;
  margin-left: 5px;
  padding: 5px;
  width: 30%;
  border: 2px solid black;
  font-size: 14px;
  color: #222;
  background-color: #fff;
  border-radius: 3px;
}
</style>
